import { FormatSpeed } from '../../utils/index'
import { Message } from '../../hooks/Message.ts'
import {FormatRemainingTime, Throttle} from '../../utils/index'

// 检查已上传的分片
async function checkUploadedChunks(Hooks: any, StoreService: any) {
  return new Promise((resolve, reject) => {
    try {
      let count = 0

      const file = StoreService.fileList.value[count]

      // 跳过已上传的文件
      if (file.fileStatus == 'success') {
        count++
        runFun()
        return
      }
      
      async function runFun() {
        // 调用用户的检查分片上传接口
        const { isExist, existList } = (await Hooks.executeHook('onCheckChunksByRequest', {
          ...file,
        })) as { isExist: boolean; existList: number[] }

        if (isExist) {
          file.fileStatus = 'success'
          file.progress = 100
          file.uploadedSize = file.fileSize
        }

        // 获取未上传的分片
        if (existList && Array.isArray(existList)) {
          existList.forEach((chunkIndex: any) => {
            file.uploadedChunks.push(chunkIndex)
            if (file.chunkList[chunkIndex]) {
              file.chunkList[chunkIndex].uploaded = true
              file.chunkList[chunkIndex].progress = 100
            }
          })
        }

        // 返回结果
        if (count >= StoreService.fileList.value.length - 1) {
          if (StoreService.fileList.value.every((i:any) => i.fileStatus === 'success')) {
            StoreService.globalUploadStatus.value = 'start'
            resolve(false)
          }
          resolve(true)
          return
        }
        count++
        runFun()
      }
      runFun()
    } catch (error) {
      reject(error)
    }
  })
}


/**
 * 压入队列
 * @param file 文件
 */
async function addQueue(Queue: any, Hooks: any, LogService: any, StoreService: any) {
  return new Promise((resolve, reject) => {
    try {
      // debugger
      let count = 0
      let chunkCount = 0

      async function runFun() {
        const file = StoreService.fileList.value[count]
        // 跳过已上传的文件
        if (file.fileStatus === 'success') {
          count++
          runFun()
          return
        }
        let tasks: any = []
        file.chunkList.forEach((chunkItem: any, chunkIndex: number) => {
          chunkCount++
          // 当前分片大小
          const currentChunkSize =
            chunkIndex < file.chunkList.length - 1
              ? file.chunkSize
              : file.fileSize % file.chunkSize || file.chunkSize
          file.startTime = Date.now()
          tasks.push({
            taskId: chunkItem.chunkHash, // 任务id
            groupId: file.fileHash, // 任务组id
            // 任务
            task: async () => {
              return new Promise((resolve, reject) => {
                chunkItem.startTime = Date.now() // 记录分片上传开始时间
                // 调用用户的检查分片上传接口
                Hooks.executeHook(
                  'onUploadChunkByRequest',
                  {
                    params: { ...chunkItem },
                    FileData: { ...file },
                  },

                  // 创建节流后的进度处理函数（500ms 触发一次）
                  Throttle((progress: any)  => {
                    // 只有当进度可计算时才处理
                    if (progress.lengthComputable) {
                      // 更新上传速度
                      file.uploadSpeed = FormatSpeed(file, chunkItem, progress)

                      // 新增：计算并更新剩余时间
                      file.remainingTime = FormatRemainingTime(file)
                    }
                  }, 500),
                  (res: any) => {
                    // 更新上传大小
                    file.uploadedSize += currentChunkSize

                    // 记录已上传分片个数
                    file.uploadedChunks.push(chunkIndex)
                    // 排序
                    file.uploadedChunks.sort((a: number, b: number) => a - b)
                    // 更新上传进度，这里取最大进度为99%，因为还有分片合并
                    file.progress = Math.min(
                      Math.round((file.uploadedChunks.length / file.chunkList.length) * 99),
                      99,
                    )
                    resolve(res)
                  },
                  (err: any) => {
                    reject(err)
                    console.log('⚠️ 分片上传意外错误', err)
                  },
                )
              })
            },
          })
        })
        // 压入队列
        await Queue?.addTask(tasks, file.fileHash)

        count++
        // 结束
        if (count >= StoreService.fileList.value.length && chunkCount === Queue.queue.length) {
          // debugger
          // 更新上传状态为 =》 成功
          // file.fileStatus = 'uploading'
          // TODO: bug在这！！！
          StoreService.fileList.value.forEach((i:any) => i.fileStatus = 'uploading')

          // 触发文件添加到上传队列钩子
          Hooks.executeHook('onFileAdded', {taskCount: chunkCount})

          // 启动队列上传
          Queue?.start()

          resolve(true)
          return
        }

        runFun()
      }
      runFun()
    } catch (error) {
      // throw new Error(error as string)
      reject(error)
    }
  })
}

/* 合并分片 */
async function mergeChunk(groupId: string, Hooks: any, LogService: any, StoreService: any) {
  return new Promise((resolve) => {
    try {
      async function runFun() {
        const file = StoreService.fileList.value.find((i:any) => i.fileHash === groupId)
        if (!file) return resolve(false)
        // 合并分片
        const result = (await Hooks.executeHook('onMergeChunkByRequest', {
          ...file,
        })) as { code: number; msg: string }
        if (result) {
          // 更新上传状态为 =》 成功
          file.fileStatus = 'success'
          // 更新上传进度为100%
          file.progress = 100
          // 新增：计算并更新剩余时间
          file.remainingTime = FormatRemainingTime(file)
          // 触发文件分片上传成功钩子
          Hooks.executeHook('onChunkMergeEnd', {fileName: file.fileName})
          resolve(true)
        } else {
          // 更新上传状态为 =》 失败
          file.fileStatus = 'error'
          resolve(false)
        }

        // 检查是否所有文件都上传完成，解锁上传状态
        const isAllUpLoaded = StoreService.fileList.value.every((i:any) => ['success', 'error'].includes(i.fileStatus))
        // debugger
        if (isAllUpLoaded) {
          // 触发文件上传完成钩子
          Hooks.executeHook('onAllComplete', null)
          StoreService.globalUploadStatus.value = 'start'
        }
      }
      runFun()
    } catch (error) {
      console.log('⚠️ 合并分片上传意外错误', error)
    }
  })
}

export default { checkUploadedChunks, addQueue, mergeChunk }
